#include "WProcess.h"

using namespace std;
using namespace log4cxx;
using namespace log4cxx::xml;
using namespace log4cxx::helpers;

WProcess::WProcess(IWbemClassObject* pclsObj)
{
	DOMConfigurator::configure("LogConfig.xml");
    this->pclsObj = pclsObj;
    setAllProperties();
}

WProcess::WProcess(WProcess& process)
{
	DOMConfigurator::configure("LogConfig.xml");
	this->pclsObj = process.pclsObj;
	setAllProperties();
}

WProcess::~WProcess()
{
}

const wstring WProcess::strProperties[] = {CAPTION, COMMAND_LINE, CREATION_CLASS_NAME, CS_CREATION_CLASS_NAME, 
CS_NAME, DESCRIPTION, EXECUTABLE_PATH, HANDLE_PROCESS, NAME,
OS_CREATION_CLASS_NAME, OS_NAME, STATUS};

const wstring WProcess::intProperties[] = {EXECUTION_STATE_PROCESS, HANDLE_COUNT, KERNEL_MODE_TIME, MAXIMUM_WORKING_SET_SIZE, 
MINIMUM_WORKING_SET_SIZE, OTHER_OPERATION_COUNT, OTHER_TRANSFER_COUNT, PAGE_FAULTS, PAGE_FILE_USAGE,
PARENT_PROCESS_ID, PEAK_PAGE_FILE_USAGE, PEAK_VIRTUAL_SIZE, PEAK_WORKING_SET_SIZE,
PRIORITY, PRIVATE_PAGE_COUNT, PROCESS_ID, QUOTA_NON_PAGED_POOL_USAGE, QUOTA_PAGED_POOL_USAGE,
QUOTA_PEAK_NON_PAGED_POOL_USAGE, QUOTA_PEAK_PAGED_POOL_USAGE, READ_OPERATION_COUNT, READ_TRANFER_COUNT,
SESSION_ID, THREAD_COUNT, USER_MODE_TIME, VIRTUAL_SIZE, WORKING_SET_SIZE, WRITE_OPERATION_COUNT,
WRITE_TRANFER_COUNT};

const wstring WProcess::dateProperties[] = {INSTALL_DATE, CREATION_DATE, TERMINATION_DATE};

void 
WProcess::setAllProperties()
{
    VARIANT vtProp;
    HRESULT hr;
    int sizeStrProperties = sizeof(strProperties) / sizeof(strProperties[0]); 
    int sizeIntProperties = sizeof(intProperties) / sizeof(intProperties[0]);
    int sizeDateProperties = sizeof(dateProperties) / sizeof(dateProperties[0]);
    
    //Set all string properties
    for(int i = 0; i < sizeStrProperties; i++)
    {
        hr = pclsObj->Get(strProperties[i].c_str(), 0, &vtProp, 0, 0);
        if(SUCCEEDED(hr))
        {
            setStringData(wstring(vtProp.bstrVal), i);
        }
    }

    //Set all int properties
    for(int i = 0; i < sizeIntProperties; i++)
    {
        hr = pclsObj->Get(intProperties[i].c_str(), 0, &vtProp, 0, 0);
        if(SUCCEEDED(hr))
        {
            setIntegerData(vtProp.intVal, i);
        }
    }

    //Set all date properties
    for(int i = 0; i < sizeDateProperties; i++)
    {
        hr = pclsObj->Get(dateProperties[i].c_str(), 0, &vtProp, 0, 0);
        if(SUCCEEDED(hr))
        {
            if(V_VT(&vtProp) != VT_NULL)
            {
                setDateData(Utils::wcharToCTime(vtProp.bstrVal), i);
            }
        }
    }
    VariantClear(&vtProp);
}

void 
WProcess::setStringData(wstring& data, int i)
{
    switch(i)
    {
    case 0:
        setCaption(data);
        break;
    case 1:
        setCommandLine(data);
        break;
    case 2:
        setCreationClassName(data);
        break;
    case 3:
        setCSCreationClassName(data);
        break;
    case 4:
        setCSName(data);
        break;
    case 5:
        setDescription(data);
        break;
    case 6:
        setExecutablePath(data);
        break;
    case 7:
        setHandle(data);
        break;
    case 8:
        setName(data);
        break;
    case 9:
        setOSCreationClassName(data);
        break;
    case 10:
        setOSName(data);
        break;
    case 11:
        setStatus(data);
        break;
    }
}

void 
WProcess::setIntegerData(int data, int i)
{
    switch(i)
    {
    case 0:
        //Not Implemented
        setExecutionState(data);
        break;
    case 1:
        setHandleCount(data);
        break;
    case 2:
        setKernelModeTime(data);
        break;
    case 3:
        setMaximumWorkingSetSize(data);
        break;
    case 4:
        setMinimumWorkingSetSize(data);
        break;
    case 5:
        setOtherOperationCount(data);
        break;
    case 6:
        setOtherTransferCount(data);
        break;
    case 7:
        setPageFaults(data);
        break;
    case 8:
        setPageFileUsage(data);
        break;
    case 9:
        setParentProcessId(data);
        break;
    case 10:
        setPeakPageFileUsage(data);
        break;
    case 11:
        setPeakVirtualSize(data);
        break;
    case 12:
        setPeakWorkingSetSize(data);
        break;
    case 13:
        setPriority(data);
        break;
    case 14:
        setPrivatePageCount(data);
        break;
    case 15:
        setProcessId(data);
        break;
    case 16:
        setQuotaNonPagedPoolUsage(data);
        break;
    case 17:
        setQuotaPagedPoolUsage(data);
        break;
    case 18:
        setQuotaPeakNonPagedPoolUsage(data);
        break;
    case 19:
        setQuotaPeakPagedPoolUsage(data);
        break;
    case 20:
        setReadOperationCount(data);
        break;
    case 21:
        setReadTransferCount(data);
        break;
    case 22:
        setSessionId(data);
        break;
    case 23:
        setThreadCount(data);
        break;
    case 24:
        setUserModeTime(data);
        break;
    case 25:
        setVirtualSize(data);
        break;
    case 26:
        setWorkingSetSize(data);
        break;
    case 27:
        setWriteOperationCount(data);
        break;
    case 28:
        setWriteTransferCount(data);
        break;
    }
}

void 
WProcess::setDateData(CTime& data, int i)
{
    switch(i)
    {
    case 0:
        //Not Implemented
        setInstallDate(data);
        break;
    case 1:
        setCreationDate(data);
        break;
    case 2:
        setTerminationDate(data);
        break;
    }
}

void 
WProcess::print()
{
	wstringstream wout;
	LoggerPtr loggerWProcess(Logger::getLogger("loggerWProcess"));
	string date=Utils::formatStd(getCreationDate());
    wstring wdate(date.begin(),date.end());
    //   wcout << CAPTION << ": " << getCaption() << endl;
    //   wcout << CREATION_CLASS_NAME << ": " << getCreationClassName() << endl;
    //   wcout << CREATION_CLASS_NAME << ": " << getCSCreationClassName() << endl;
    //   wcout << CS_NAME << ": "  << getCSName() << endl;
    //   wcout << DESCRIPTION << ": "  << getDescription() << endl;
    //   wcout << EXECUTABLE_PATH << ": "  << getExecutablePath() << endl;
    //   wcout << EXECUTION_STATE_PROCESS << ": " << getExecutionState() << endl;
    //   wcout << HANDLE_PROCESS << ": "  << getHandle() << endl;
    //   wcout << HANDLE_COUNT << ": "  << getHandleCount() << endl;
    //   wcout << INSTALL_DATE << ": ";
    //cout << Utils::formatStd(getInstallDate()) << endl;
    //   wcout << KERNEL_MODE_TIME << ": "  << getKernelModeTime() << endl;
    //   wcout << MAXIMUM_WORKING_SET_SIZE << ": "  << getMaximumWorkingSetSize() << " " <<KILOBYTES << endl;
    //   wcout << MINIMUM_WORKING_SET_SIZE << ": "  << getMinimumWorkingSetSize() << " " << KILOBYTES << endl;
    wout << NAME << ": "  << getName() << endl;
    wout << CREATION_DATE << ": " << wdate;
    
    //   wcout << OS_CREATION_CLASS_NAME << ": " << getOSCreationClassName() << endl;
    wout << OS_NAME << ": "  << Utils::getOSNameProcessed(getOSName()) << endl;
    //   wcout << OTHER_OPERATION_COUNT << ": "  << getOtherOperationCount() << endl;
    //   wcout << OTHER_TRANSFER_COUNT << ": "  << getOtherTransferCount() << " " << BYTES << endl;
    //   wcout << PAGE_FAULTS << ": "  << getPageFaults() << endl;
    //   wcout << PAGE_FILE_USAGE << ": " << getPageFileUsage() << " " << KILOBYTES << endl;
    //   wcout << PARENT_PROCESS_ID << ": " << getParentProcessId() << endl;
    //   wcout << PEAK_PAGE_FILE_USAGE << ": " << getPeakPageFileUsage() << " " << KILOBYTES<< endl;
    //   wcout << PEAK_VIRTUAL_SIZE << ": " << getPeakVirtualSize() << " " << BYTES << endl;
    //   wcout << PEAK_WORKING_SET_SIZE << ": "  << getPeakWorkingSetSize() << " " << KILOBYTES << endl;
    //   wcout << PRIORITY << ": " << getPriority() << endl;
    //   wcout << PRIVATE_PAGE_COUNT << ": " << getPrivatePageCount() << endl;
    wout << PROCESS_ID << ": " << getProcessId() << endl;
    //   wcout << QUOTA_NON_PAGED_POOL_USAGE<< ": " << getQuotaNonPagedPoolUsage() << endl;
    //   wcout << QUOTA_PAGED_POOL_USAGE << ": " << getQuotaPagedPoolUsage() << endl;
    //   wcout << QUOTA_PEAK_NON_PAGED_POOL_USAGE << ": " << getQuotaPeakNonPagedPoolUsage() << endl;
    //   wcout << QUOTA_PEAK_PAGED_POOL_USAGE << ": " << getQuotaPeakPagedPoolUsage() << endl;
    //   wcout << READ_OPERATION_COUNT << ": " << getReadOperationCount() << endl;
    //   wcout << READ_TRANFER_COUNT << ": " << getReadTransferCount() << " " << BYTES << endl;
    //   wcout << SESSION_ID << ": "  << getSessionId() << endl;
    //   wcout << STATUS << ": "  << endl;
    //   wcout << TERMINATION_DATE << ": ";
    //cout << Utils::formatStd(getTerminationDate()) << endl;
    //   wcout << THREAD_COUNT << ": " << getThreadCount() << endl;
    //   wcout << USER_MODE_TIME << ": " << getUserModeTime() << " " << NANOSECONDS << endl;
    //   wcout << VIRTUAL_SIZE << ": " << getVirtualSize() << " " << BYTES << endl;
    //   wcout << WINDOWS_VERSION << ": " << getWindowsVersion() << endl;
    //   wcout << WORKING_SET_SIZE << ": " << getWorkingSetSize() << endl;
    //   wcout << WRITE_OPERATION_COUNT << ": " << getWriteOperationCount() << endl;
    //   wcout << WRITE_TRANFER_COUNT << ": " << getWriteTransferCount() << " " << BYTES << endl;

	LOG4CXX_INFO(loggerWProcess,wout.str());
}